﻿namespace ScrumLite.Data
{
    using System;
    using System.Linq;

    public class DeliverableStore: IDeliverableStore
    {        

        public Deliverable[] GetDeliverables(string projectId)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                IQueryable<Deliverable> results = (from e in context.Deliverables
                                                 where e.pk_project == new Guid(projectId)
                                                 orderby e.releasedOn descending
                                                 select e);                

                return results.ToArray();
            }
        }

        public Deliverable GetDeliverable(Guid id)
        {            
            using (ScrumLite.Data.ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                return context.Deliverables.Single(d => d.id == id);
            }
        }

        public WorkArea[] GetWorkAreas(Guid idDeliverable)
        {
            using(ScrumLiteDataContext context = new  ScrumLiteDataContext())
            {
                IQueryable<WorkArea> workAreas = (from wa in context.DeliverableWorkAreas                                                  
                                                  where wa.pk_deliverable == idDeliverable
                                                  select wa.WorkArea);

                return workAreas.ToArray();
                
            }            
        }

        public Guid GetDeliverableByMoniker(string projectId, int moniker)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                var query = (from de in context.Deliverables
                             where de.moniker == moniker
                             where de.pk_project == new Guid(projectId)
                             select de.id);
                            
                return query.First();
            }
        }

        public Deliverable[] GetDeliverablesByWorkArea(WorkArea workArea)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {

                var query = from dwa in context.DeliverableWorkAreas
                            where dwa.pk_workarea == workArea.id
                            select dwa.Deliverable;
                                                                     
                return query.ToArray();
            }


        }

        public void Add(Deliverable deliverable)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                context.Log = new DebuggerWriter();
                context.Deliverables.InsertOnSubmit(deliverable);
                
                context.SubmitChanges();
            }
        }

        public void Update(Deliverable deliverable)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                var original = context.Deliverables.SingleOrDefault(d => d.id == deliverable.id);

                if (original != null)
                {
                    // Remove existing workareas associated to the deliverable
                    context.DeliverableWorkAreas.DeleteAllOnSubmit(original.DeliverableWorkAreas);

                    System.Data.Linq.EntitySet<DeliverableWorkArea> deliverableWorkAreas = new System.Data.Linq.EntitySet<DeliverableWorkArea>();
                    foreach (DeliverableWorkArea dwa in deliverable.DeliverableWorkAreas)
                    {
                        deliverableWorkAreas.Add(new DeliverableWorkArea { id = dwa.id, pk_deliverable = dwa.pk_deliverable, pk_workarea = dwa.pk_workarea });
                    }

                    original.pk_project = deliverable.pk_project;
                    original.fileName = deliverable.fileName;
                    original.uri_repository = deliverable.uri_repository;
                    original.releasedOn = deliverable.releasedOn;
                    original.DeliverableWorkAreas = deliverableWorkAreas;

                    context.SubmitChanges();
                }
            }
        }

        public int RetrieveLastMoniker(string projectId)
        {
            using (ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                var query = from deliverable in context.Deliverables
                            where deliverable.pk_project == new Guid(projectId)
                            select deliverable.moniker;

                if (query.Count() > 0)
                {
                    return query.Max();
                }
                else
                {
                    return 0;
                }
            }
        }
        
        public bool IsDefect(Guid idDeliverable)
        {
            bool result = false;

            using (ScrumLite.Data.ScrumLiteDataContext context = new ScrumLiteDataContext())
            {
                var query = (from e in context.Defects
                            where e.fk_deliverable == idDeliverable
                            select e);

                if (query.Count() > 0)
                {
                    result = true;
                }
            }
            return result;
        }
    }
}
